/*
 * =============================================================================
 * "THE BEER-WARE LICENSE" (Revision 42):
 * <eirikb@google.com> wrote this file. As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return Eirik Brandtzæg
 * =============================================================================
 */
package no.eirikb.robotec.terminal.element;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import no.eirikb.robotec.terminal.Terminal;

/**
 *
 * @author eirikb
 * @author <a href="mailto:eirikb@google.com">eirikb@google.com</a>
 */
public abstract class Command extends Element {

    private enum COMMAND {

        UNKNOWN, EXIT, CAT, KILL;

        public static COMMAND getCommand(String line) {
            try {
                return valueOf(line.toUpperCase());
            } catch (Exception e) {
            }
            return UNKNOWN;
        }
    }
    private String readLine;
    private boolean echo;
    private boolean showPrompt;

    public Command(Terminal terminal) {
        super(terminal);
        echo = true;
        showPrompt = true;
        readLine = "";
    }

    public Command(Terminal terminal, int x, int y, int width, int height) {
        super(terminal, x, y, width, height);
        echo = true;
        showPrompt = true;
        readLine = "";
    }

    @Override
    public void init() {
        prompt();
    }

    @Override
    public void read(int c) {
        if (c != 13) {
            readLine += (char) c;
            if (echo) {
                try {
                    getTerminal().getServer().getSocket().getOutputStream().write(c);
                } catch (IOException ex) {
                    Logger.getLogger(Terminal.class.getName()).log(Level.SEVERE, null, ex);
                }

            }
        } else {
            readLine(readLine);
            readLine = "";
        }
    }

    public void readLine(String line) {
        StringTokenizer st = new StringTokenizer(line, " ");
        String cmd = st.nextToken().trim();
        switch (COMMAND.getCommand(cmd)) {
            case EXIT:
                sendLine("Closing terminal connection...");
                getTerminal().getServer().sendLagText("\r\n");
                getTerminal().getServer().close();
                showPrompt = false;
                break;
            case CAT:
                cat(st.nextToken());
                break;
            case KILL:
                System.exit(0);
                break;
            case UNKNOWN:
                sendLine("Unknown command: " + cmd);
                break;
        }
        prompt();
    }

    private void cat(String fileName) {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(getTerminal().getFile().getAbsolutePath() + "/" + fileName)));
            String line;
            while ((line = reader.readLine()) != null) {
                sendLine(line);
            }
        } catch (IOException ex) {
            sendLine("File not found");
            Logger.getLogger(CommandBox.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException ex) {
                Logger.getLogger(CommandBox.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void prompt() {
        if (showPrompt) {
            sendLine("> ");
        }
    }

    public void sendLine(String line) {
        getTerminal().getServer().sendLagText("\r\n" + line);
    }

    public String getReadLine() {
        return readLine;
    }

    public void setReadLine(String readLine) {
        this.readLine = readLine;
    }

    public boolean isEcho() {
        return echo;
    }
}
